package com.oyjd.fw.ws;

import java.net.InetAddress;
import java.net.NetworkInterface;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.annotation.PostConstruct;
import javax.jws.WebService;
import javax.xml.ws.Binding;
import javax.xml.ws.Endpoint;
import javax.xml.ws.handler.Handler;

import org.apache.log4j.Logger;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;


/**
 * webservice初始化和发布
 * 
 * @author 欧建东
 * @email oyjd@163.com
 */
@Component
public class WebServicePublish implements ApplicationContextAware, DisposableBean {
	private static Logger log = Logger.getLogger(WebServicePublish.class);
	private ApplicationContext applicationContext;
	private WebServicePara webServicePara = new WebServicePara();
	private List<Endpoint> epList = new ArrayList<Endpoint>();

	/**
	 * 注入webservice参数
	 * 
	 * @param webServicePara
	 */
	@Autowired(required = false)
	public void setWebServicePara(WebServicePara webServicePara) {
		this.webServicePara = webServicePara;
	}

	/**
	 * 注入spring环境
	 */
	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
		this.applicationContext = applicationContext;
	}

	/**
	 * 销毁
	 */
	public void destroy() throws Exception {
		for (Endpoint ep : epList) {
			ep.stop();
		}
		webServicePara = null;
		applicationContext = null;
	}

	/**
	 * 初始化并发布webservice
	 */
	@SuppressWarnings("rawtypes")
	@PostConstruct
	public void init() {
		List<String> ipList = getLocalIpList();
		Map<String, Object> m = applicationContext.getBeansWithAnnotation(WebService.class);
		for (Iterator<String> item = m.keySet().iterator(); item.hasNext();) {
			String key = item.next();
			Object ws = m.get(key);
			for (String ip : ipList) {
				String publishPath = getPublishPath(ip, key);
				try {
					Endpoint endpoint = Endpoint.create(ws);
					Binding binding = endpoint.getBinding();
					List<Handler> handlerChain = new ArrayList<Handler>();
					handlerChain.add(new ServerHandler());
					binding.setHandlerChain(handlerChain);
					endpoint.publish(publishPath);							
					epList.add(endpoint);
					System.out.println(" WebService -> " + publishPath + "?wsdl");
				} catch (Exception err) {
					log.error(publishPath + "发布失败！" + err.getMessage(), err);
				}

			}
		}
	}

	/**
	 * 组合发布路径
	 * 
	 * @param ip
	 * @param sp
	 * @param wsName
	 * @return
	 */
	private String getPublishPath(String ip, String wsName) {
		StringBuffer sb = new StringBuffer();
		sb.append("http://");
		sb.append(ip);
		sb.append(":");
		sb.append(webServicePara.getPort());
		sb.append(webServicePara.getContentPath());
		sb.append("/");
		sb.append(wsName);
		return sb.toString();
	}

	/**
	 * 获取本机ip列表
	 * 
	 * @return
	 */
	private List<String> getLocalIpList() {
		List<String> list = new ArrayList<String>();
		try {
			Enumeration<NetworkInterface> netInterfaces = NetworkInterface.getNetworkInterfaces();
			while (netInterfaces.hasMoreElements()) {
				NetworkInterface ni = netInterfaces.nextElement();
				Enumeration<InetAddress> ips = ni.getInetAddresses();
				while (ips.hasMoreElements()) {
					String ip = ips.nextElement().getHostAddress();
					list.add(ip);
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return list;
	}

}
